#include "rtsp_h264liveSource.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

#include <limits.h>
#include "pthread.h"

#define mSleep(ms) usleep(ms * 1000)

rtsp_h264liveSrouce::rtsp_h264liveSrouce(UsageEnvironment &env, CRingBuffer<vidPacket> *ring_buf) : FramedSource(env),
																m_pToken(0),
																m_pFrameBuffer(0),
																m_hFifo(0),
																_h264_ringBuf(ring_buf)
{



	pthread_mutex_init(&_mutex, NULL);

	_fTruncatedBytes = (char *)malloc( TRUNCATEDBUFFSIZE );
	_fTruncatedBytesNum = 0;

}

rtsp_h264liveSrouce::~rtsp_h264liveSrouce(void)
{
	if (m_hFifo)
	{
		::close(m_hFifo);
	}

	envir().taskScheduler().unscheduleDelayedTask(m_pToken);


	pthread_mutex_destroy(&_mutex);

	free(_fTruncatedBytes);

	printf("[MEDIA SERVER] rtsp connection closed\n");
}

int32_t rtsp_h264liveSrouce::get_fps()
{

	static int32_t cnt = 0;
	static int64_t last_ttime = 0, this_time = 0;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	cnt++;
	this_time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
	if (this_time - last_ttime > 1000)
	{
		printf("fps = %d\r\n", cnt);
		cnt = 0;
		last_ttime = this_time;
	}
	return cnt;
}

void rtsp_h264liveSrouce::doGetNextFrame()
{

	fFrameSize = 0;
	struct vidPacket frame_buf;
	if (_h264_ringBuf->ReadData( &frame_buf ) > 0)
	{
		// printf("i=%d framelen=%d time=%ld \n",i,framelen,struVExtra.ullTimeStamp);
		fFrameSize = frame_buf.size;
		if (fFrameSize > fMaxSize)
		{
			fFrameSize = fMaxSize;
			int frBufUsedBytes = fMaxSize;
			fNumTruncatedBytes = frame_buf.size - frBufUsedBytes;
			printf("Truncat %d bytes\n",fNumTruncatedBytes);
			memmove(fTo, frame_buf.buffer, frBufUsedBytes);
			memmove(_fTruncatedBytes, frame_buf.buffer + frBufUsedBytes, fNumTruncatedBytes);
			_fTruncatedBytesNum = fNumTruncatedBytes;
		}
		else
		{
			if (_fTruncatedBytesNum > 0)
			{
				memmove(fTo, _fTruncatedBytes, _fTruncatedBytesNum);
				memmove(fTo + _fTruncatedBytesNum, frame_buf.buffer, frame_buf.size);
				fFrameSize += _fTruncatedBytesNum;
				_fTruncatedBytesNum = 0;
			}
			else
			{
				memmove(fTo, frame_buf.buffer, frame_buf.size);
			}
		}
	}
	fDurationInMicroseconds = 1000000 / 30;
	nextTask() = envir().taskScheduler().scheduleDelayedTask(30000, (TaskFunc *)FramedSource::afterGetting, this);
}

unsigned int rtsp_h264liveSrouce::maxFrameSize() const
{
	return 1024 * 100;
}
